#!/usr/bin/env python
from __future__ import division
import pygame
from pygame.locals import *
from utils import *
from stroke_parsing import *
import tempfile

import sys
sys.path.append("mathtex-0.3")
from matplotlib.mathtext import MathTextParser
from matplotlib import rc
rc('text', usetex=True)


def rescale(xy):
    x,y = xy
    return [x*SCREEN_X/800,y*SCREEN_Y/600]

SCREEN_X,SCREEN_Y = 1400,900
FONTSIZE = SCREEN_X//30
LINEWIDTH = SCREEN_X//400

DIMeraser = [rescale([85, 50]), rescale([85+35, 49+30])]
DIMequals = [rescale([60, 470]), rescale([60+50, 470+30])]
DIMwriting = [rescale([120, 50]), rescale([120+670, 50+260])]

MTP = MathTextParser("bitmap")

class Gooey:
    
    def render(self,tex_str):        
        pngfile = "eqn.png"
        self.screen.blit(self.bg,(0,0))        
        self.draw_strokes()
        try:
            eqn_obj = MTP.to_png(pngfile,"$"+tex_str+"$",fontsize=FONTSIZE)
            eqn_image = pygame.image.load(pngfile)
            self.screen.blit(eqn_image,rescale([160, 450]))
        except Exception: pass
        
        
    def __init__(self):
        # Initialize PyGame
        pygame.init()
        self.stroke = []
        self.strokes = []
        self.TFwriting = False
        icon = pygame.image.load('icon.jpg')
        pygame.display.set_icon(icon)
        pygame.display.set_caption('WYOMING')
        bg = pygame.image.load('bg.png')
        self.bg = pygame.transform.scale(bg,(SCREEN_X,SCREEN_Y))
        self.screen = pygame.display.set_mode((SCREEN_X,SCREEN_Y))
        self.screen.blit(self.bg, (0,0))

        
    def run(self):
        #import wingdbstub
        # Update display initially
        pygame.display.update()
        # Run the event loop
        self.loop()
        # Close the Pygame window
        pygame.quit()

    def loop(self):
        clock = pygame.time.Clock()
        exit = False
        while not exit:
            clock.tick(60)
            exit = self.handleEvents()
            #self.screen.blit(self.bg, (0, 0))
            pygame.display.update()
            
    def handleEvents(self):
        POScursor = pygame.mouse.get_pos()
        b1,b2,b3 = pygame.mouse.get_pressed()
        exit = False
        for event in pygame.event.get():
            if event.type == QUIT:
                exit = True
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    exit = True
                elif event.key == K_BACKSPACE:
                    self.eraseStroke()
                elif event.key == K_x:
                    self.clearAllStrokes()
            elif event.type == MOUSEBUTTONDOWN:
                if self.inRange(POScursor, DIMwriting):
                    self.stroke.append(POScursor)
                    self.TFwriting = True
                elif self.inRange(POScursor, DIMeraser):
                # Erase last stroke
                    self.eraseStroke()
                elif self.inRange(POScursor, DIMequals):
                # Convert to LaTex
                    self.evaluate()                                                      
            elif event.type == MOUSEMOTION:
                #POScursor = pygame.mouse.get_pos()
                #b1,b2,b3 = pygame.mouse.get_pressed()
                if b1 == True & self.TFwriting == True:
                    # Continue stroke 
                    if self.inRange(POScursor, DIMwriting):
                        #self.paintCircle(POScursor)
                        cur_point = (POScursor[0], POScursor[1])
                        pygame.draw.line(self.screen, (0,0,0), self.stroke[-1], cur_point, LINEWIDTH)                        
                        self.stroke.append(cur_point)
                    # Stop and erase stroke
                    else:
                        self.strokes.append(self.stroke)
                        self.stroke = []
                        self.TFwriting = False
                        self.eraseStroke()
            elif event.type == MOUSEBUTTONUP:
                # Add stroke to stroke list
                if self.TFwriting == True:
                    if len(self.stroke) > 1:
                        self.stroke = self.stroke[1:]
                    self.strokes.append(self.stroke)
                    self.stroke = []
                    self.TFwriting = False
                    self.latexIt()             

        return exit

    def inRange(self, pos, box):
        return box[0][0] <= pos[0] and pos[0] <= box[1][0] and \
               box[0][1] <= pos[1] and pos[1] <= box[1][1]

    def paintCircle(self, pos):
        pygame.draw.circle(self.screen,(0,0,0),pos,2,2)
        pygame.display.update()

    def draw_strokes(self):
        for s in self.strokes:
            for pos1,pos2 in zip(s[:-1],s[1:]):
                pygame.draw.line(self.screen, (0,0,0), pos1,pos2, LINEWIDTH)                        

        pygame.display.update()
        


    def eraseStroke(self):
        if len(self.strokes) >= 1:
            self.strokes.pop()
            revert_caches(len(self.strokes))
            self.latexIt()
            self.draw_strokes()

    def latexIt(self):
        self.result = parse_strokes(self.strokes) if len(self.strokes) >= 1 else ""
        save_caches(len(self.strokes))
        self.render(self.result)
        pygame.display.update()

    def clearAllStrokes(self):
        self.strokes = []
        revert_caches(0)
        self.screen.blit(self.bg, (0,0))
        pygame.display.update()
        
    def evaluate(self):
        try:
            self.render(str(eval(self.result)))
            pygame.display.update()       
        except Exception:
            pass
        print self.result
        
        
# Start the game
if __name__ == "__main__":
    g = Gooey().run()
